package com.sketch.commom.aop;

import com.alibaba.fastjson.JSON;
import com.sketch.commom.Result;
import com.sketch.commom.annotation.UserStatus;
import com.sketch.commom.utils.JwtUtil;
import com.sketch.entity.SysUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

import static com.sketch.commom.CodeMsg.UNAUTHORIZED;
import static com.sketch.commom.Context.UserContext;
import static com.sketch.commom.utils.JwtUtil.JWT_SECRET;

//@Aspect
//@Component
public class TokenAop {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Pointcut("within(com.sketch.controller..*)")
    public void userPointcut() {
        // Method is empty as this is just a Pointcut, the implementations are in the
        // advices.
    }

    @Around("userPointcut()")
    public Object userAround(ProceedingJoinPoint joinPoint) throws Throwable {

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method targetMethod = methodSignature.getMethod();
        UserStatus userStatus = targetMethod.getAnnotation(UserStatus.class);

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        String token = "";
        // 需要验证token的接口
        if (userStatus == null || userStatus.isLogin()) {
            // 从请求中获取 Token
             token = request.getHeader("token");
            // 校验 Token
            if (token == null || !isValidToken(token)) {
                // Token 无效，返回错误响应
                return Result.error(UNAUTHORIZED);
            }
            String session = JwtUtil.getSession(token);
            SysUser user = JSON.parseObject(session, SysUser.class);
            UserContext.set(user);
        }
        return joinPoint.proceed();
    }
    private boolean isValidToken(String token) {
        Jws<Claims> claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(JWT_SECRET)
                    .parseClaimsJws(token);
        } catch (ExpiredJwtException e) {
            //token过期
            return false;
        } catch (Exception e) {
            //token解析异常
            return false;
        }
        return claims.getBody().getExpiration().getTime() - System.currentTimeMillis()>1;
    }
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
